@layer-ai/core 0.6.0 → 0.7.1
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/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/lib/db/postgres.d.ts +16 -1
- package/dist/lib/db/postgres.d.ts.map +1 -1
- package/dist/lib/db/postgres.js +38 -1
- package/dist/lib/encryption.d.ts +9 -0
- package/dist/lib/encryption.d.ts.map +1 -0
- package/dist/lib/encryption.js +39 -0
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ export { authenticate } from './middleware/auth.js';
|
|
|
7
7
|
export type {} from './middleware/auth.js';
|
|
8
8
|
export { db } from './lib/db/postgres.js';
|
|
9
9
|
export { default as redis } from './lib/db/redis.js';
|
|
10
|
+
export { encrypt, decrypt, generateEncryptionKey } from './lib/encryption.js';
|
|
11
|
+
export type { EncryptedData } from '@layer-ai/sdk';
|
|
10
12
|
export declare const createSessionKey: (userId: string) => Promise<string>;
|
|
11
13
|
export declare const deleteSessionKeysForUser: (userId: string) => Promise<void>;
|
|
12
14
|
export * from './services/task-analysis.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAG3C,OAAO,EAAE,EAAE,EAAE,MAAM,sBAAsB,CAAC;AAC1C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAGrD,eAAO,MAAM,gBAAgB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,MAAM,CAGrE,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAG3E,CAAC;AAGF,cAAc,6BAA6B,CAAC;AAG5C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGpE,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAG3C,OAAO,EAAE,EAAE,EAAE,MAAM,sBAAsB,CAAC;AAC1C,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAGrD,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC9E,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,eAAO,MAAM,gBAAgB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,MAAM,CAGrE,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAU,QAAQ,MAAM,KAAG,OAAO,CAAC,IAAI,CAG3E,CAAC;AAGF,cAAc,6BAA6B,CAAC;AAG5C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,WAAW,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -9,6 +9,8 @@ export { authenticate } from './middleware/auth.js';
|
|
|
9
9
|
// Database
|
|
10
10
|
export { db } from './lib/db/postgres.js';
|
|
11
11
|
export { default as redis } from './lib/db/redis.js';
|
|
12
|
+
// Encryption
|
|
13
|
+
export { encrypt, decrypt, generateEncryptionKey } from './lib/encryption.js';
|
|
12
14
|
// Session Key Utilities (for Next.js auth)
|
|
13
15
|
export const createSessionKey = async (userId) => {
|
|
14
16
|
const { db } = await import('./lib/db/postgres.js');
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import pg from 'pg';
|
|
2
|
-
import type { User, ApiKey, Gate } from '@layer-ai/sdk';
|
|
2
|
+
import type { User, ApiKey, Gate, ProviderKey } from '@layer-ai/sdk';
|
|
3
3
|
declare function getPool(): pg.Pool;
|
|
4
4
|
export declare const db: {
|
|
5
5
|
query(text: string, params?: any[]): Promise<pg.QueryResult<any>>;
|
|
@@ -25,6 +25,21 @@ export declare const db: {
|
|
|
25
25
|
} | null>;
|
|
26
26
|
createSessionKey(userId: string): Promise<string>;
|
|
27
27
|
deleteSessionKeysForUser(userId: string): Promise<void>;
|
|
28
|
+
getProviderKey(userId: string, provider: string): Promise<ProviderKey | null>;
|
|
29
|
+
getProviderKeys(userId: string): Promise<ProviderKey[]>;
|
|
30
|
+
createProviderKey(userId: string, provider: string, encryptedKey: {
|
|
31
|
+
encrypted: string;
|
|
32
|
+
iv: string;
|
|
33
|
+
authTag: string;
|
|
34
|
+
}, keyPrefix: string): Promise<ProviderKey>;
|
|
35
|
+
updateProviderKey(userId: string, provider: string, encryptedKey: {
|
|
36
|
+
encrypted: string;
|
|
37
|
+
iv: string;
|
|
38
|
+
authTag: string;
|
|
39
|
+
}, keyPrefix: string): Promise<ProviderKey | null>;
|
|
40
|
+
deleteProviderKey(userId: string, provider: string): Promise<boolean>;
|
|
41
|
+
hardDeleteProviderKey(userId: string, provider: string): Promise<boolean>;
|
|
42
|
+
getDeletedProviderKeys(daysOld?: number): Promise<ProviderKey[]>;
|
|
28
43
|
};
|
|
29
44
|
export default getPool;
|
|
30
45
|
//# sourceMappingURL=postgres.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/lib/db/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAyB,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../../../src/lib/db/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAyB,WAAW,EAAE,MAAM,eAAe,CAAC;AAO5F,iBAAS,OAAO,IAAI,EAAE,CAAC,IAAI,CAqB1B;AA0BD,eAAO,MAAM,EAAE;gBAEK,MAAM,WAAW,GAAG,EAAE;0BASZ,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;oBAQnC,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;sBAQ3B,MAAM,gBAAgB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;6BASrC,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;yBAQnC,MAAM,WAAW,MAAM,aAAa,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;kCAQjE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;8BAO1B,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;qBAQnC,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;iCAS7B,MAAM,YAAY,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;+BAQjD,MAAM,UAAU,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;4BAQhD,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;uBAQ7B,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;oBA4BpC,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;mBAQ9B,MAAM,QAAQ,GAAG,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;mBA4CxC,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;qBASvB,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC;iCAgBP,MAAM,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;6BAQhE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;qCAehB,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;2BAQhC,MAAM,YAAY,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;4BAQrD,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;8BASnD,MAAM,YACJ,MAAM,gBACF;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,aACrD,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC;8BAWb,MAAM,YACJ,MAAM,gBACF;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,aACrD,MAAM,GAChB,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;8BAWE,MAAM,YAAY,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;kCAQvC,MAAM,YAAY,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;qCAQzC,MAAM,GAAQ,OAAO,CAAC,WAAW,EAAE,CAAC;CAU3E,CAAC;AAEF,eAAe,OAAO,CAAC"}
|
package/dist/lib/db/postgres.js
CHANGED
|
@@ -196,6 +196,43 @@ export const db = {
|
|
|
196
196
|
},
|
|
197
197
|
async deleteSessionKeysForUser(userId) {
|
|
198
198
|
await getPool().query('DELETE FROM session_keys WHERE user_id = $1', [userId]);
|
|
199
|
-
}
|
|
199
|
+
},
|
|
200
|
+
// Provider Keys (BYOK)
|
|
201
|
+
async getProviderKey(userId, provider) {
|
|
202
|
+
const result = await getPool().query('SELECT * FROM provider_keys WHERE user_id = $1 AND provider = $2 AND deleted_at IS NULL', [userId, provider]);
|
|
203
|
+
return result.rows[0] ? toCamelCase(result.rows[0]) : null;
|
|
204
|
+
},
|
|
205
|
+
async getProviderKeys(userId) {
|
|
206
|
+
const result = await getPool().query('SELECT * FROM provider_keys WHERE user_id = $1 AND deleted_at IS NULL ORDER BY created_at DESC', [userId]);
|
|
207
|
+
return result.rows.map(toCamelCase);
|
|
208
|
+
},
|
|
209
|
+
async createProviderKey(userId, provider, encryptedKey, keyPrefix) {
|
|
210
|
+
const result = await getPool().query(`INSERT INTO provider_keys (user_id, provider, encrypted_key, key_prefix)
|
|
211
|
+
VALUES ($1, $2, $3, $4)
|
|
212
|
+
RETURNING *`, [userId, provider, JSON.stringify(encryptedKey), keyPrefix]);
|
|
213
|
+
return toCamelCase(result.rows[0]);
|
|
214
|
+
},
|
|
215
|
+
async updateProviderKey(userId, provider, encryptedKey, keyPrefix) {
|
|
216
|
+
const result = await getPool().query(`UPDATE provider_keys
|
|
217
|
+
SET encrypted_key = $3, key_prefix = $4, deleted_at = NULL, updated_at = NOW()
|
|
218
|
+
WHERE user_id = $1 AND provider = $2
|
|
219
|
+
RETURNING *`, [userId, provider, JSON.stringify(encryptedKey), keyPrefix]);
|
|
220
|
+
return result.rows[0] ? toCamelCase(result.rows[0]) : null;
|
|
221
|
+
},
|
|
222
|
+
async deleteProviderKey(userId, provider) {
|
|
223
|
+
const result = await getPool().query('UPDATE provider_keys SET deleted_at = NOW() WHERE user_id = $1 AND provider = $2 AND deleted_at IS NULL', [userId, provider]);
|
|
224
|
+
return (result.rowCount ?? 0) > 0;
|
|
225
|
+
},
|
|
226
|
+
async hardDeleteProviderKey(userId, provider) {
|
|
227
|
+
const result = await getPool().query('DELETE FROM provider_keys WHERE user_id = $1 AND provider = $2', [userId, provider]);
|
|
228
|
+
return (result.rowCount ?? 0) > 0;
|
|
229
|
+
},
|
|
230
|
+
async getDeletedProviderKeys(daysOld = 90) {
|
|
231
|
+
const result = await getPool().query(`SELECT * FROM provider_keys
|
|
232
|
+
WHERE deleted_at IS NOT NULL
|
|
233
|
+
AND deleted_at < NOW() - INTERVAL '1 day' * $1
|
|
234
|
+
ORDER BY deleted_at ASC`, [daysOld]);
|
|
235
|
+
return result.rows.map(toCamelCase);
|
|
236
|
+
},
|
|
200
237
|
};
|
|
201
238
|
export default getPool;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface EncryptedData {
|
|
2
|
+
encrypted: string;
|
|
3
|
+
iv: string;
|
|
4
|
+
authTag: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function encrypt(plaintext: string, masterKey: string): EncryptedData;
|
|
7
|
+
export declare function decrypt(encryptedData: EncryptedData, masterKey: string): string;
|
|
8
|
+
export declare function generateEncryptionKey(): string;
|
|
9
|
+
//# sourceMappingURL=encryption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../../src/lib/encryption.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,CAqB3E;AAED,wBAAgB,OAAO,CAAC,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAmB/E;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv, randomBytes } from "crypto";
|
|
2
|
+
export function encrypt(plaintext, masterKey) {
|
|
3
|
+
if (!plaintext) {
|
|
4
|
+
throw new Error("Plaintext is required");
|
|
5
|
+
}
|
|
6
|
+
if (!masterKey || masterKey.length !== 64) {
|
|
7
|
+
throw new Error("Master key must be a 64-character hex string (32 bytes)");
|
|
8
|
+
}
|
|
9
|
+
const iv = randomBytes(12);
|
|
10
|
+
const keyBuffer = Buffer.from(masterKey, "hex");
|
|
11
|
+
const cipher = createCipheriv("aes-256-gcm", keyBuffer, iv);
|
|
12
|
+
let encrypted = cipher.update(plaintext, "utf-8", "hex");
|
|
13
|
+
encrypted += cipher.final("hex");
|
|
14
|
+
const authTag = cipher.getAuthTag();
|
|
15
|
+
return {
|
|
16
|
+
encrypted,
|
|
17
|
+
iv: iv.toString("hex"),
|
|
18
|
+
authTag: authTag.toString("hex"),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function decrypt(encryptedData, masterKey) {
|
|
22
|
+
if (!encryptedData || !encryptedData.encrypted || !encryptedData.iv || !encryptedData.authTag) {
|
|
23
|
+
throw new Error("Invalid encrypted data structure");
|
|
24
|
+
}
|
|
25
|
+
if (!masterKey || masterKey.length !== 64) {
|
|
26
|
+
throw new Error("Master key must be a 64-character hex string (32 bytes)");
|
|
27
|
+
}
|
|
28
|
+
const keyBuffer = Buffer.from(masterKey, "hex");
|
|
29
|
+
const ivBuffer = Buffer.from(encryptedData.iv, "hex");
|
|
30
|
+
const authTagBuffer = Buffer.from(encryptedData.authTag, "hex");
|
|
31
|
+
const decipher = createDecipheriv("aes-256-gcm", keyBuffer, ivBuffer);
|
|
32
|
+
decipher.setAuthTag(authTagBuffer);
|
|
33
|
+
let decrypted = decipher.update(encryptedData.encrypted, "hex", "utf8");
|
|
34
|
+
decrypted += decipher.final("utf8");
|
|
35
|
+
return decrypted;
|
|
36
|
+
}
|
|
37
|
+
export function generateEncryptionKey() {
|
|
38
|
+
return randomBytes(32).toString("hex");
|
|
39
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@layer-ai/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "Core API routes and services for Layer AI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"nanoid": "^5.0.4",
|
|
37
37
|
"openai": "^4.24.0",
|
|
38
38
|
"pg": "^8.11.3",
|
|
39
|
-
"@layer-ai/sdk": "^0.
|
|
39
|
+
"@layer-ai/sdk": "^0.7.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@types/bcryptjs": "^2.4.6",
|