streamby-core 0.31.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +283 -283
- package/dist/adapters/database/connectionManager.js +83 -78
- package/dist/adapters/database/sql.js +1 -1
- package/dist/middleware/routes/dbConnection.js +46 -210
- package/dist/middleware/routes/storage.js +2 -42
- package/dist/models/Model.js +9 -9
- package/dist/services/connectionResolver.d.ts +19 -0
- package/dist/services/connectionResolver.js +127 -0
- package/dist/services/executor.d.ts +5 -0
- package/dist/services/executor.js +44 -15
- package/dist/types/index.d.ts +12 -0
- package/dist/types/nodePersistence.d.ts +3 -0
- package/dist/types/nodePersistence.js +15 -0
- package/package.json +63 -63
- package/dist/utils/crypto.d.ts +0 -3
- package/dist/utils/crypto.js +0 -32
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Pool } from 'pg';
|
|
2
|
+
import { MongoClient } from 'mongodb';
|
|
3
|
+
import { StreamByConfig, Auth, DbConnection, StorageConnection, StorageAdapter } from '../types';
|
|
4
|
+
export type ResolvedDbClient = {
|
|
5
|
+
client: Pool | MongoClient;
|
|
6
|
+
type: 'sql' | 'nosql';
|
|
7
|
+
ephemeral: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type ResolveError = {
|
|
10
|
+
error: string;
|
|
11
|
+
status: number;
|
|
12
|
+
};
|
|
13
|
+
export declare function findDbConnection(project: any, connId: string): DbConnection | undefined;
|
|
14
|
+
export declare function findStorageConnection(project: any, connId: string): StorageConnection | undefined;
|
|
15
|
+
export declare function resolveDbConnectionClient(project: any, connId: string, config: StreamByConfig, auth: Auth): Promise<ResolvedDbClient | ResolveError>;
|
|
16
|
+
export declare function releaseDbClient(resolved: ResolvedDbClient): Promise<void>;
|
|
17
|
+
export declare function resolveStorageAdapter(project: any, connId: string, config: StreamByConfig & {
|
|
18
|
+
adapter?: StorageAdapter;
|
|
19
|
+
}, auth: Auth): Promise<StorageAdapter | ResolveError>;
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.findDbConnection = findDbConnection;
|
|
4
|
+
exports.findStorageConnection = findStorageConnection;
|
|
5
|
+
exports.resolveDbConnectionClient = resolveDbConnectionClient;
|
|
6
|
+
exports.releaseDbClient = releaseDbClient;
|
|
7
|
+
exports.resolveStorageAdapter = resolveStorageAdapter;
|
|
8
|
+
const pg_1 = require("pg");
|
|
9
|
+
const mongodb_1 = require("mongodb");
|
|
10
|
+
const connectionManager_1 = require("../adapters/database/connectionManager");
|
|
11
|
+
const builtinAccess_1 = require("../utils/builtinAccess");
|
|
12
|
+
const userIntegration_1 = require("./userIntegration");
|
|
13
|
+
const encryption_1 = require("../utils/encryption");
|
|
14
|
+
const storage_1 = require("../providers/storage");
|
|
15
|
+
const s3_1 = require("../adapters/storage/s3");
|
|
16
|
+
function findDbConnection(project, connId) {
|
|
17
|
+
return project.dbConnections?.find((c) => c.id === connId);
|
|
18
|
+
}
|
|
19
|
+
function findStorageConnection(project, connId) {
|
|
20
|
+
return project.storageConnections?.find((c) => c.id === connId);
|
|
21
|
+
}
|
|
22
|
+
// `connId` must be the `id` of a real row in project.dbConnections — never a bare
|
|
23
|
+
// config id (config.databases[].id). Builtin rows reuse the shared pooled client keyed by
|
|
24
|
+
// conn.integrationId (config id); BYOC/manual rows open a short-lived client from their own
|
|
25
|
+
// decrypted credential, which the caller must close via `releaseDbClient` once done.
|
|
26
|
+
async function resolveDbConnectionClient(project, connId, config, auth) {
|
|
27
|
+
const conn = findDbConnection(project, connId);
|
|
28
|
+
if (!conn)
|
|
29
|
+
return { error: 'DB connection not found', status: 404 };
|
|
30
|
+
if (conn.source === 'builtin') {
|
|
31
|
+
const builtinId = conn.integrationId;
|
|
32
|
+
if (!(await (0, builtinAccess_1.assertBuiltinAccess)(auth, builtinId, config, 'database'))) {
|
|
33
|
+
return { error: 'Access to this built-in database is not permitted', status: 403 };
|
|
34
|
+
}
|
|
35
|
+
const db = (config.databases ?? []).find(d => d.id === builtinId);
|
|
36
|
+
if (!db)
|
|
37
|
+
return { error: `Database '${builtinId}' not found in config`, status: 404 };
|
|
38
|
+
try {
|
|
39
|
+
const { client, type } = (0, connectionManager_1.getConnection)(builtinId);
|
|
40
|
+
return { client: client, type, ephemeral: false };
|
|
41
|
+
}
|
|
42
|
+
catch (e) {
|
|
43
|
+
return { error: e.message, status: 503 };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
let connectionString;
|
|
47
|
+
if (conn.source === 'integration') {
|
|
48
|
+
if (!conn.integrationId)
|
|
49
|
+
return { error: 'Connection is missing its integrationId', status: 500 };
|
|
50
|
+
const credential = await (0, userIntegration_1.getDecryptedIntegrationCredentialById)(conn.integrationId);
|
|
51
|
+
if (!credential)
|
|
52
|
+
return { error: 'Integration not found', status: 400 };
|
|
53
|
+
connectionString = credential;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
if (!(0, encryption_1.isEncryptionKeySet)())
|
|
57
|
+
return { error: 'Encryption key is not set', status: 500 };
|
|
58
|
+
if (!conn.encryptedCredential)
|
|
59
|
+
return { error: 'Connection has no stored credential', status: 400 };
|
|
60
|
+
connectionString = (0, encryption_1.decrypt)(conn.encryptedCredential);
|
|
61
|
+
}
|
|
62
|
+
const type = conn.dbType === 'postgresql' ? 'sql' : 'nosql';
|
|
63
|
+
try {
|
|
64
|
+
if (type === 'sql') {
|
|
65
|
+
const pool = new pg_1.Pool({ connectionString });
|
|
66
|
+
await pool.query('SELECT 1');
|
|
67
|
+
return { client: pool, type, ephemeral: true };
|
|
68
|
+
}
|
|
69
|
+
const client = new mongodb_1.MongoClient(connectionString);
|
|
70
|
+
await client.connect();
|
|
71
|
+
return { client, type, ephemeral: true };
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
return { error: `Failed to connect: ${e.message}`, status: 503 };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Only closes clients this resolver opened itself (`ephemeral: true`) — the shared pooled
|
|
78
|
+
// builtin clients are owned by connectionManager and must outlive a single request.
|
|
79
|
+
async function releaseDbClient(resolved) {
|
|
80
|
+
if (!resolved.ephemeral)
|
|
81
|
+
return;
|
|
82
|
+
if (resolved.type === 'sql')
|
|
83
|
+
await resolved.client.end();
|
|
84
|
+
else
|
|
85
|
+
await resolved.client.close();
|
|
86
|
+
}
|
|
87
|
+
async function resolveStorageAdapter(project, connId, config, auth) {
|
|
88
|
+
const conn = findStorageConnection(project, connId);
|
|
89
|
+
if (!conn)
|
|
90
|
+
return { error: 'Storage connection not found', status: 404 };
|
|
91
|
+
if (conn.source === 'builtin') {
|
|
92
|
+
const builtinId = conn.integrationId;
|
|
93
|
+
if (!(await (0, builtinAccess_1.assertBuiltinAccess)(auth, builtinId, config, 'storage'))) {
|
|
94
|
+
return { error: 'Access to this built-in storage is not permitted', status: 403 };
|
|
95
|
+
}
|
|
96
|
+
const provider = config.storageProviders.find(p => p.id === builtinId);
|
|
97
|
+
if (!provider)
|
|
98
|
+
return { error: 'Storage provider not found', status: 404 };
|
|
99
|
+
if (provider.type === 's3')
|
|
100
|
+
return new s3_1.S3Adapter(provider.config);
|
|
101
|
+
return config.adapter || (0, storage_1.createStorageProvider)(config.storageProviders);
|
|
102
|
+
}
|
|
103
|
+
if (conn.source === 'integration') {
|
|
104
|
+
if (!conn.integrationId)
|
|
105
|
+
return { error: 'Connection is missing its integrationId', status: 500 };
|
|
106
|
+
try {
|
|
107
|
+
const s3Config = await (0, userIntegration_1.getDecryptedIntegrationCredentialById)(conn.integrationId);
|
|
108
|
+
if (!s3Config)
|
|
109
|
+
return { error: 'Integration not found', status: 400 };
|
|
110
|
+
return new s3_1.S3Adapter(s3Config);
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
return { error: `Failed to initialize storage adapter: ${e.message}`, status: 500 };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (!(0, encryption_1.isEncryptionKeySet)())
|
|
117
|
+
return { error: 'Encryption key not set', status: 500 };
|
|
118
|
+
if (!conn.encryptedCredential)
|
|
119
|
+
return { error: 'Connection has no stored credential', status: 400 };
|
|
120
|
+
try {
|
|
121
|
+
const s3Config = JSON.parse((0, encryption_1.decrypt)(conn.encryptedCredential));
|
|
122
|
+
return new s3_1.S3Adapter(s3Config);
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
return { error: `Failed to initialize storage adapter: ${e.message}`, status: 500 };
|
|
126
|
+
}
|
|
127
|
+
}
|
|
@@ -1,2 +1,7 @@
|
|
|
1
1
|
import { NodeSchema, StreamByConfig } from '../types';
|
|
2
|
+
export declare class NodeExecutionError extends Error {
|
|
3
|
+
nodeId: string;
|
|
4
|
+
nodeType: string;
|
|
5
|
+
constructor(nodeId: string, nodeType: string, message: string);
|
|
6
|
+
}
|
|
2
7
|
export declare function executeExport(nodeSchema: NodeSchema, project: any, config: StreamByConfig): Promise<any>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NodeExecutionError = void 0;
|
|
3
4
|
exports.executeExport = executeExport;
|
|
4
|
-
const connectionManager_1 = require("../adapters/database/connectionManager");
|
|
5
5
|
const encryption_1 = require("../utils/encryption");
|
|
6
6
|
const dbConnection_1 = require("./dbConnection");
|
|
7
|
+
const connectionResolver_1 = require("./connectionResolver");
|
|
7
8
|
const jobQueue_1 = require("./jobQueue");
|
|
8
9
|
const mediaProcessor_1 = require("./mediaProcessor");
|
|
9
10
|
const vfxProcessor_1 = require("./vfxProcessor");
|
|
@@ -75,6 +76,21 @@ function getTarget(nodes, edges, sourceId, sourceHandle) {
|
|
|
75
76
|
const edge = edges.find(e => e.source === sourceId && e.sourceHandle === sourceHandle);
|
|
76
77
|
return edge ? (nodes.find(n => n.id === edge.target) ?? null) : null;
|
|
77
78
|
}
|
|
79
|
+
class NodeExecutionError extends Error {
|
|
80
|
+
constructor(nodeId, nodeType, message) {
|
|
81
|
+
super(message);
|
|
82
|
+
this.nodeId = nodeId;
|
|
83
|
+
this.nodeType = nodeType;
|
|
84
|
+
this.name = 'NodeExecutionError';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
exports.NodeExecutionError = NodeExecutionError;
|
|
88
|
+
// Export execution is public (gated by allowedOrigin, not user identity — see
|
|
89
|
+
// export.ts:339) — there is no real Auth to pass through. This sentinel satisfies
|
|
90
|
+
// resolveDbConnectionClient's signature without adding a gate that never existed;
|
|
91
|
+
// canUseBuiltin gating is for connection *management* by a user, not for serving an
|
|
92
|
+
// already-published export.
|
|
93
|
+
const SYSTEM_AUTH = { userId: 'system', username: 'system', role: 'admin' };
|
|
78
94
|
async function executeExport(nodeSchema, project, config) {
|
|
79
95
|
const nodes = nodeSchema.nodes;
|
|
80
96
|
const edges = nodeSchema.edges;
|
|
@@ -94,24 +110,26 @@ async function executeExport(nodeSchema, project, config) {
|
|
|
94
110
|
const tableName = (node.data?.tableName || node.data?.subtitle || node.data?.label);
|
|
95
111
|
if (!tableName)
|
|
96
112
|
continue;
|
|
113
|
+
// dataSourceNode always declares its own database connection explicitly (persistence:
|
|
114
|
+
// 'database' in types/nodePersistence.ts) — a project has no notion of a "default"
|
|
115
|
+
// connection, since a project can have many database/storage/API providers connected.
|
|
97
116
|
const connectionId = node.data?.connectionId;
|
|
117
|
+
if (!connectionId) {
|
|
118
|
+
throw new NodeExecutionError(node.id, node.type, `Node '${node.id}' (${node.type}) has no database connection — connect one on the node.`);
|
|
119
|
+
}
|
|
98
120
|
const recordId = node.data?.recordId;
|
|
99
121
|
const projectIdentifier = project._id?.toString() ?? project.id;
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (connectionId) {
|
|
104
|
-
const { client, type } = (0, connectionManager_1.getConnection)(connectionId);
|
|
105
|
-
dataResults.push(await fetchData(client, type));
|
|
122
|
+
const resolved = await (0, connectionResolver_1.resolveDbConnectionClient)(project, connectionId, config, SYSTEM_AUTH);
|
|
123
|
+
if ('error' in resolved) {
|
|
124
|
+
throw new NodeExecutionError(node.id, node.type, `Node '${node.id}' (${node.type}): ${resolved.error}`);
|
|
106
125
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
dataResults.push(await fetchData(client, type));
|
|
126
|
+
try {
|
|
127
|
+
dataResults.push(recordId
|
|
128
|
+
? await (0, dbConnection_1.queryRecordByIdInternal)(resolved.client, resolved.type, tableName, recordId, projectIdentifier)
|
|
129
|
+
: await (0, dbConnection_1.queryRecordsInternal)(resolved.client, resolved.type, tableName, 500, 0, projectIdentifier));
|
|
130
|
+
}
|
|
131
|
+
finally {
|
|
132
|
+
await (0, connectionResolver_1.releaseDbClient)(resolved);
|
|
115
133
|
}
|
|
116
134
|
}
|
|
117
135
|
else if (node.type === 'connectionNode') {
|
|
@@ -170,6 +188,17 @@ async function executeExport(nodeSchema, project, config) {
|
|
|
170
188
|
payload = { ...payload, jobId: job.jobId, jobType: 'thumbnail' };
|
|
171
189
|
}
|
|
172
190
|
else if (processNode.type === 'ingestNode' && fileId) {
|
|
191
|
+
// ingestNode always declares its own storage connection explicitly (persistence:
|
|
192
|
+
// 'storage' in types/nodePersistence.ts) — a project has no notion of a "default"
|
|
193
|
+
// connection, since a project can have many database/storage/API providers connected.
|
|
194
|
+
const storageConnectionId = nodeData.storageConnectionId;
|
|
195
|
+
if (!storageConnectionId) {
|
|
196
|
+
throw new NodeExecutionError(processNode.id, processNode.type, `Node '${processNode.id}' (${processNode.type}) has no storage connection — connect one on the node.`);
|
|
197
|
+
}
|
|
198
|
+
const storageResolved = await (0, connectionResolver_1.resolveStorageAdapter)(project, storageConnectionId, config, SYSTEM_AUTH);
|
|
199
|
+
if ('error' in storageResolved) {
|
|
200
|
+
throw new NodeExecutionError(processNode.id, processNode.type, `Node '${processNode.id}' (${processNode.type}): ${storageResolved.error}`);
|
|
201
|
+
}
|
|
173
202
|
const job = (0, jobQueue_1.createJob)('ingest', systemUserId, projectId, nodeData);
|
|
174
203
|
setImmediate(() => (0, mediaProcessor_1.runIngestJob)(job.jobId, fileId, projectId));
|
|
175
204
|
payload = { ...payload, jobId: job.jobId, jobType: 'ingest' };
|
package/dist/types/index.d.ts
CHANGED
|
@@ -78,6 +78,18 @@ export interface ProjectInfo {
|
|
|
78
78
|
storageConnections?: StorageConnection[];
|
|
79
79
|
pipelines?: PipelineRef[];
|
|
80
80
|
builtinBackfilledAt?: Date;
|
|
81
|
+
workflow?: Workflow;
|
|
82
|
+
}
|
|
83
|
+
export type NodePersistence = 'database' | 'storage' | 'both' | 'none';
|
|
84
|
+
export interface Workflow {
|
|
85
|
+
id: string;
|
|
86
|
+
name: string;
|
|
87
|
+
description?: string;
|
|
88
|
+
status: string;
|
|
89
|
+
projectId: string;
|
|
90
|
+
nodeSchema: NodeSchema | null;
|
|
91
|
+
createdAt: Date;
|
|
92
|
+
updatedAt: Date;
|
|
81
93
|
}
|
|
82
94
|
export type ConnectionMethod = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';
|
|
83
95
|
export interface Connection {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NODE_PERSISTENCE = void 0;
|
|
4
|
+
exports.getNodePersistence = getNodePersistence;
|
|
5
|
+
// Only node types that write to a real database/storage connection need an entry here.
|
|
6
|
+
// Process nodes (transcodeNode, captionNode, etc.) operate on a fileId already resolved by
|
|
7
|
+
// the internal job pipeline (mediaProcessor.ts), not directly on project connections, so
|
|
8
|
+
// they're 'none' — same for filter/deliverable/distribution/annotation/connection nodes.
|
|
9
|
+
exports.NODE_PERSISTENCE = {
|
|
10
|
+
dataSourceNode: 'database',
|
|
11
|
+
ingestNode: 'storage',
|
|
12
|
+
};
|
|
13
|
+
function getNodePersistence(nodeType) {
|
|
14
|
+
return exports.NODE_PERSISTENCE[nodeType] ?? 'none';
|
|
15
|
+
}
|
package/package.json
CHANGED
|
@@ -1,63 +1,63 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "streamby-core",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "StreamBy middleware framework for media storage management",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"types": "dist/index.d.ts",
|
|
7
|
-
"files": [
|
|
8
|
-
"dist"
|
|
9
|
-
],
|
|
10
|
-
"scripts": {
|
|
11
|
-
"build": "tsc",
|
|
12
|
-
"test": "vitest",
|
|
13
|
-
"dev": "ts-node-dev --respawn --clear dev.ts",
|
|
14
|
-
"prepublishOnly": "npm run build"
|
|
15
|
-
},
|
|
16
|
-
"repository": {
|
|
17
|
-
"type": "git",
|
|
18
|
-
"url": "https://github.com/GwerhDev/StreamBy-Package.git"
|
|
19
|
-
},
|
|
20
|
-
"keywords": [
|
|
21
|
-
"streamby",
|
|
22
|
-
"middleware",
|
|
23
|
-
"upload",
|
|
24
|
-
"storage",
|
|
25
|
-
"s3",
|
|
26
|
-
"express",
|
|
27
|
-
"typescript"
|
|
28
|
-
],
|
|
29
|
-
"author": "TerminalCore Labs",
|
|
30
|
-
"license": "MIT",
|
|
31
|
-
"dependencies": {
|
|
32
|
-
"@aws-sdk/client-s3": "^3.528.0",
|
|
33
|
-
"@aws-sdk/s3-request-presigner": "^3.787.0",
|
|
34
|
-
"@prisma/client": "^6.12.0",
|
|
35
|
-
"bcrypt": "^5.1.1",
|
|
36
|
-
"dotenv": "^16.5.0",
|
|
37
|
-
"express": "^4.0.0",
|
|
38
|
-
"mongodb": "^6.17.0",
|
|
39
|
-
"mongoose": "^8.13.2",
|
|
40
|
-
"node-fetch": "^3.0.0",
|
|
41
|
-
"pg": "^8.16.3",
|
|
42
|
-
"prisma": "^6.12.0",
|
|
43
|
-
"ws": "^8.20.0"
|
|
44
|
-
},
|
|
45
|
-
"devDependencies": {
|
|
46
|
-
"@types/bcrypt": "^5.0.2",
|
|
47
|
-
"@types/cors": "^2.8.18",
|
|
48
|
-
"@types/express": "^4.17.17",
|
|
49
|
-
"@types/mongodb": "^4.0.7",
|
|
50
|
-
"@types/node": "^22.15.21",
|
|
51
|
-
"@types/pg": "^8.15.4",
|
|
52
|
-
"@types/supertest": "^6.0.3",
|
|
53
|
-
"@types/ws": "^8.18.1",
|
|
54
|
-
"cors": "^2.8.5",
|
|
55
|
-
"supertest": "^7.1.4",
|
|
56
|
-
"ts-node-dev": "^2.0.0",
|
|
57
|
-
"typescript": "^5.8.3",
|
|
58
|
-
"vitest": "^3.1.1"
|
|
59
|
-
},
|
|
60
|
-
"peerDependencies": {
|
|
61
|
-
"express": "^4.0.0"
|
|
62
|
-
}
|
|
63
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "streamby-core",
|
|
3
|
+
"version": "0.32.0",
|
|
4
|
+
"description": "StreamBy middleware framework for media storage management",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"test": "vitest",
|
|
13
|
+
"dev": "ts-node-dev --respawn --clear dev.ts",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/GwerhDev/StreamBy-Package.git"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"streamby",
|
|
22
|
+
"middleware",
|
|
23
|
+
"upload",
|
|
24
|
+
"storage",
|
|
25
|
+
"s3",
|
|
26
|
+
"express",
|
|
27
|
+
"typescript"
|
|
28
|
+
],
|
|
29
|
+
"author": "TerminalCore Labs",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"@aws-sdk/client-s3": "^3.528.0",
|
|
33
|
+
"@aws-sdk/s3-request-presigner": "^3.787.0",
|
|
34
|
+
"@prisma/client": "^6.12.0",
|
|
35
|
+
"bcrypt": "^5.1.1",
|
|
36
|
+
"dotenv": "^16.5.0",
|
|
37
|
+
"express": "^4.0.0",
|
|
38
|
+
"mongodb": "^6.17.0",
|
|
39
|
+
"mongoose": "^8.13.2",
|
|
40
|
+
"node-fetch": "^3.0.0",
|
|
41
|
+
"pg": "^8.16.3",
|
|
42
|
+
"prisma": "^6.12.0",
|
|
43
|
+
"ws": "^8.20.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/bcrypt": "^5.0.2",
|
|
47
|
+
"@types/cors": "^2.8.18",
|
|
48
|
+
"@types/express": "^4.17.17",
|
|
49
|
+
"@types/mongodb": "^4.0.7",
|
|
50
|
+
"@types/node": "^22.15.21",
|
|
51
|
+
"@types/pg": "^8.15.4",
|
|
52
|
+
"@types/supertest": "^6.0.3",
|
|
53
|
+
"@types/ws": "^8.18.1",
|
|
54
|
+
"cors": "^2.8.5",
|
|
55
|
+
"supertest": "^7.1.4",
|
|
56
|
+
"ts-node-dev": "^2.0.0",
|
|
57
|
+
"typescript": "^5.8.3",
|
|
58
|
+
"vitest": "^3.1.1"
|
|
59
|
+
},
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"express": "^4.0.0"
|
|
62
|
+
}
|
|
63
|
+
}
|
package/dist/utils/crypto.d.ts
DELETED
package/dist/utils/crypto.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.encrypt = encrypt;
|
|
7
|
-
exports.decrypt = decrypt;
|
|
8
|
-
exports.hash = hash;
|
|
9
|
-
const crypto_1 = __importDefault(require("crypto"));
|
|
10
|
-
const ALGORITHM = 'aes-256-cbc';
|
|
11
|
-
const IV_LENGTH = 16;
|
|
12
|
-
function encrypt(text, secretKey) {
|
|
13
|
-
const iv = crypto_1.default.randomBytes(IV_LENGTH);
|
|
14
|
-
const key = crypto_1.default.createHash('sha256').update(String(secretKey)).digest('base64').substr(0, 32);
|
|
15
|
-
const cipher = crypto_1.default.createCipheriv(ALGORITHM, Buffer.from(key), iv);
|
|
16
|
-
let encrypted = cipher.update(text);
|
|
17
|
-
encrypted = Buffer.concat([encrypted, cipher.final()]);
|
|
18
|
-
return iv.toString('hex') + ':' + encrypted.toString('hex');
|
|
19
|
-
}
|
|
20
|
-
function decrypt(text, secretKey) {
|
|
21
|
-
const textParts = text.split(':');
|
|
22
|
-
const iv = Buffer.from(textParts.shift(), 'hex');
|
|
23
|
-
const encryptedText = Buffer.from(textParts.join(':'), 'hex');
|
|
24
|
-
const key = crypto_1.default.createHash('sha256').update(String(secretKey)).digest('base64').substr(0, 32);
|
|
25
|
-
const decipher = crypto_1.default.createDecipheriv(ALGORITHM, Buffer.from(key), iv);
|
|
26
|
-
let decrypted = decipher.update(encryptedText);
|
|
27
|
-
decrypted = Buffer.concat([decrypted, decipher.final()]);
|
|
28
|
-
return decrypted.toString();
|
|
29
|
-
}
|
|
30
|
-
function hash(text) {
|
|
31
|
-
return crypto_1.default.createHash('sha256').update(text).digest('hex');
|
|
32
|
-
}
|