@sockethub/data-layer 1.0.0-alpha.12 → 1.0.0-alpha.14
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 +1 -1
- package/dist/credentials-store.d.ts +140 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +12398 -2227
- package/dist/index.js.map +16 -18
- package/dist/job-base.d.ts +44 -0
- package/dist/job-queue.d.ts +68 -0
- package/dist/job-worker.d.ts +58 -0
- package/dist/queue-id.d.ts +2 -0
- package/{src/types.ts → dist/types.d.ts} +2 -13
- package/package.json +9 -9
- package/src/credentials-store.test.ts +0 -171
- package/src/credentials-store.ts +0 -192
- package/src/index.ts +0 -36
- package/src/job-base.ts +0 -125
- package/src/job-queue.test.ts +0 -295
- package/src/job-queue.ts +0 -247
- package/src/job-worker.test.ts +0 -142
- package/src/job-worker.ts +0 -116
- package/src/queue-id.test.ts +0 -17
- package/src/queue-id.ts +0 -14
package/README.md
CHANGED
|
@@ -56,7 +56,7 @@ encryption/decryption and session-based isolation.
|
|
|
56
56
|
**Dependencies:**
|
|
57
57
|
|
|
58
58
|
- Redis server (6.0+)
|
|
59
|
-
- `@sockethub/crypto` for encryption
|
|
59
|
+
- `@sockethub/util` (`@sockethub/util/crypto`) for encryption
|
|
60
60
|
- `@sockethub/schemas` for type definitions
|
|
61
61
|
|
|
62
62
|
## API Documentation
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import type { CredentialsObject } from "@sockethub/schemas";
|
|
2
|
+
import { type Redis } from "ioredis";
|
|
3
|
+
import SecureStore from "secure-store-redis";
|
|
4
|
+
import type { RedisConfig } from "./types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Creates or returns a shared Redis connection for CredentialsStore instances.
|
|
7
|
+
* This prevents connection exhaustion by reusing a single connection across
|
|
8
|
+
* all credential storage operations.
|
|
9
|
+
*
|
|
10
|
+
* @param config - Redis configuration
|
|
11
|
+
* @returns Shared Redis connection instance
|
|
12
|
+
*/
|
|
13
|
+
export declare function createCredentialsRedisConnection(config: RedisConfig): Redis;
|
|
14
|
+
/**
|
|
15
|
+
* Creates or returns a dedicated shared Redis connection for HTTP idempotency.
|
|
16
|
+
*/
|
|
17
|
+
export declare function createIdempotencyRedisConnection(config: RedisConfig): Redis;
|
|
18
|
+
/**
|
|
19
|
+
* Creates or returns a dedicated shared Redis connection for rate limiting.
|
|
20
|
+
* A dedicated connection keeps rate-limit traffic off the credentials and
|
|
21
|
+
* idempotency connections and lets a Redis-backed limiter share request budgets
|
|
22
|
+
* across instances.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createRateLimitRedisConnection(config: RedisConfig): Redis;
|
|
25
|
+
/**
|
|
26
|
+
* Resets the shared credentials Redis connection. Used primarily for testing.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resetSharedCredentialsRedisConnection(): Promise<void>;
|
|
29
|
+
export declare function resetSharedIdempotencyRedisConnection(): Promise<void>;
|
|
30
|
+
export declare function resetSharedRateLimitRedisConnection(): Promise<void>;
|
|
31
|
+
export interface CredentialsStoreInterface {
|
|
32
|
+
get(actor: string, credentialsHash?: string, options?: CredentialsValidationOptions): Promise<CredentialsObject | undefined>;
|
|
33
|
+
save(actor: string, creds: CredentialsObject): Promise<number>;
|
|
34
|
+
/**
|
|
35
|
+
* Delete this session's entire credential namespace from Redis. Used by
|
|
36
|
+
* single-use sessions (e.g. HTTP actions requests) whose credentials are
|
|
37
|
+
* never read again once the request completes. Optional: long-lived socket
|
|
38
|
+
* sessions do not implement it.
|
|
39
|
+
*/
|
|
40
|
+
teardown?(): Promise<void>;
|
|
41
|
+
}
|
|
42
|
+
export interface CredentialsStoreOptions {
|
|
43
|
+
/**
|
|
44
|
+
* Sliding time-to-live in milliseconds applied to this session's
|
|
45
|
+
* credential key in Redis, refreshed on every save and read. A backstop
|
|
46
|
+
* against keys orphaned by crashes or ungraceful shutdowns where explicit
|
|
47
|
+
* teardown never runs — size it generously (idle sessions do not refresh
|
|
48
|
+
* it). Omit or 0 to disable expiry.
|
|
49
|
+
*/
|
|
50
|
+
ttlMs?: number;
|
|
51
|
+
}
|
|
52
|
+
export interface CredentialsValidationOptions {
|
|
53
|
+
/**
|
|
54
|
+
* Enables stricter checks used only when trying to attach a second socket
|
|
55
|
+
* session to an already-running actor-scoped platform instance.
|
|
56
|
+
*/
|
|
57
|
+
validateSessionShare?: boolean;
|
|
58
|
+
}
|
|
59
|
+
export declare class CredentialsMismatchError extends Error {
|
|
60
|
+
constructor(message: string);
|
|
61
|
+
}
|
|
62
|
+
export declare class CredentialsNotShareableError extends Error {
|
|
63
|
+
constructor(message: string);
|
|
64
|
+
}
|
|
65
|
+
export declare function verifySecureStore(config: RedisConfig): Promise<void>;
|
|
66
|
+
/**
|
|
67
|
+
* Secure, encrypted storage for user credentials with session-based isolation.
|
|
68
|
+
*
|
|
69
|
+
* Provides automatic encryption/decryption of credential objects stored in Redis,
|
|
70
|
+
* ensuring that sensitive authentication data is never stored in plaintext.
|
|
71
|
+
* Each session gets its own isolated credential store.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const store = new CredentialsStore('session123', secret, redisConfig);
|
|
76
|
+
*
|
|
77
|
+
* // Store credentials
|
|
78
|
+
* await store.save('user@example.com', {
|
|
79
|
+
* username: 'user',
|
|
80
|
+
* password: 'secret',
|
|
81
|
+
* server: 'irc.freenode.net'
|
|
82
|
+
* });
|
|
83
|
+
*
|
|
84
|
+
* // Retrieve credentials
|
|
85
|
+
* const creds = await store.get('user@example.com', credentialsHash);
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
export declare class CredentialsStore implements CredentialsStoreInterface {
|
|
89
|
+
readonly uid: string;
|
|
90
|
+
store: SecureStore;
|
|
91
|
+
objectHash: (o: unknown) => string;
|
|
92
|
+
private readonly log;
|
|
93
|
+
/**
|
|
94
|
+
* Creates a new CredentialsStore instance.
|
|
95
|
+
*
|
|
96
|
+
* @param parentId - Unique identifier for the parent instance (e.g. server ID)
|
|
97
|
+
* @param sessionId - Client session identifier for credential isolation
|
|
98
|
+
* @param secret - 32-character encryption secret for credential security
|
|
99
|
+
* @param redisConfig - Redis connection configuration
|
|
100
|
+
* @throws Error if secret is not exactly 32 characters
|
|
101
|
+
*/
|
|
102
|
+
constructor(parentId: string, sessionId: string, secret: string, redisConfig: RedisConfig, options?: CredentialsStoreOptions);
|
|
103
|
+
initCrypto(): void;
|
|
104
|
+
initSecureStore(secret: string, redisConfig: RedisConfig, ttlMs?: number): void;
|
|
105
|
+
/**
|
|
106
|
+
* Gets the credentials for a given actor ID.
|
|
107
|
+
* @param actor
|
|
108
|
+
* @param credentialsHash - Optional hash to validate credentials.
|
|
109
|
+
* If undefined, validation is skipped.
|
|
110
|
+
*/
|
|
111
|
+
get(actor: string, credentialsHash?: string, options?: CredentialsValidationOptions): Promise<CredentialsObject>;
|
|
112
|
+
/**
|
|
113
|
+
* Saves the credentials for a given actor ID
|
|
114
|
+
* @param actor
|
|
115
|
+
* @param creds
|
|
116
|
+
*/
|
|
117
|
+
save(actor: string, creds: CredentialsObject): Promise<number>;
|
|
118
|
+
/**
|
|
119
|
+
* Delete this session's entire credential hash from Redis, promptly
|
|
120
|
+
* reclaiming the key instead of waiting for its TTL (if any) to lapse.
|
|
121
|
+
* Called when the session ends (socket disconnect, HTTP actions request
|
|
122
|
+
* cleanup). Best-effort and safe to call when nothing was stored — a
|
|
123
|
+
* missing key is a no-op.
|
|
124
|
+
*/
|
|
125
|
+
teardown(): Promise<void>;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Delete every credential-store key belonging to `parentId`. Called from
|
|
129
|
+
* server shutdown so an instance reclaims its own keys instead of stranding
|
|
130
|
+
* them under a parentId that no future boot will ever reference (each boot
|
|
131
|
+
* randomizes its parentId). Scoped strictly to the given parentId: Redis may
|
|
132
|
+
* be shared by multiple running instances, so keys under other parentIds are
|
|
133
|
+
* never touched. Returns the number of keys removed.
|
|
134
|
+
*/
|
|
135
|
+
export declare function purgeCredentialsStoreKeys(client: Redis, parentId: string): Promise<number>;
|
|
136
|
+
/**
|
|
137
|
+
* Convenience wrapper over {@link purgeCredentialsStoreKeys} using the shared
|
|
138
|
+
* credentials Redis connection.
|
|
139
|
+
*/
|
|
140
|
+
export declare function purgeCredentialsStores(parentId: string, config: RedisConfig): Promise<number>;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { CredentialsMismatchError, CredentialsNotShareableError, CredentialsStore, type CredentialsStoreInterface, type CredentialsStoreOptions, type CredentialsValidationOptions, createCredentialsRedisConnection, createIdempotencyRedisConnection, createRateLimitRedisConnection, purgeCredentialsStoreKeys, purgeCredentialsStores, resetSharedCredentialsRedisConnection, resetSharedIdempotencyRedisConnection, resetSharedRateLimitRedisConnection } from "./credentials-store.js";
|
|
2
|
+
import { getRedisConnectionCount, resetSharedRedisConnection } from "./job-base.js";
|
|
3
|
+
import { JobQueue } from "./job-queue.js";
|
|
4
|
+
import { JobWorker, type JobWorkerOptions } from "./job-worker.js";
|
|
5
|
+
export * from "./types.js";
|
|
6
|
+
import type { RedisConfig } from "./types.js";
|
|
7
|
+
declare function redisCheck(config: RedisConfig): Promise<void>;
|
|
8
|
+
export { CredentialsMismatchError, CredentialsNotShareableError, CredentialsStore, type CredentialsStoreInterface, type CredentialsStoreOptions, type CredentialsValidationOptions, createCredentialsRedisConnection, createIdempotencyRedisConnection, createRateLimitRedisConnection, getRedisConnectionCount, JobQueue, purgeCredentialsStoreKeys, purgeCredentialsStores, JobWorker, type JobWorkerOptions, redisCheck, resetSharedCredentialsRedisConnection, resetSharedIdempotencyRedisConnection, resetSharedRateLimitRedisConnection, resetSharedRedisConnection, };
|