@qwickapps/server 1.5.2 → 1.6.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/core/control-panel.js +8 -8
  3. package/dist/core/control-panel.js.map +1 -1
  4. package/dist/plugins/api-keys/api-keys-plugin.d.ts +46 -0
  5. package/dist/plugins/api-keys/api-keys-plugin.d.ts.map +1 -0
  6. package/dist/plugins/api-keys/api-keys-plugin.js +329 -0
  7. package/dist/plugins/api-keys/api-keys-plugin.js.map +1 -0
  8. package/dist/plugins/api-keys/index.d.ts +14 -0
  9. package/dist/plugins/api-keys/index.d.ts.map +1 -0
  10. package/dist/plugins/api-keys/index.js +17 -0
  11. package/dist/plugins/api-keys/index.js.map +1 -0
  12. package/dist/plugins/api-keys/middleware/bearer-token-auth.d.ts +74 -0
  13. package/dist/plugins/api-keys/middleware/bearer-token-auth.d.ts.map +1 -0
  14. package/dist/plugins/api-keys/middleware/bearer-token-auth.js +201 -0
  15. package/dist/plugins/api-keys/middleware/bearer-token-auth.js.map +1 -0
  16. package/dist/plugins/api-keys/middleware/index.d.ts +7 -0
  17. package/dist/plugins/api-keys/middleware/index.d.ts.map +1 -0
  18. package/dist/plugins/api-keys/middleware/index.js +7 -0
  19. package/dist/plugins/api-keys/middleware/index.js.map +1 -0
  20. package/dist/plugins/api-keys/stores/index.d.ts +7 -0
  21. package/dist/plugins/api-keys/stores/index.d.ts.map +1 -0
  22. package/dist/plugins/api-keys/stores/index.js +7 -0
  23. package/dist/plugins/api-keys/stores/index.js.map +1 -0
  24. package/dist/plugins/api-keys/stores/postgres-store.d.ts +34 -0
  25. package/dist/plugins/api-keys/stores/postgres-store.d.ts.map +1 -0
  26. package/dist/plugins/api-keys/stores/postgres-store.js +360 -0
  27. package/dist/plugins/api-keys/stores/postgres-store.js.map +1 -0
  28. package/dist/plugins/api-keys/types.d.ts +268 -0
  29. package/dist/plugins/api-keys/types.d.ts.map +1 -0
  30. package/dist/plugins/api-keys/types.js +56 -0
  31. package/dist/plugins/api-keys/types.js.map +1 -0
  32. package/dist/plugins/auth/auth-plugin.js +1 -1
  33. package/dist/plugins/auth/auth-plugin.js.map +1 -1
  34. package/dist/plugins/auth/env-config.js +2 -2
  35. package/dist/plugins/auth/env-config.js.map +1 -1
  36. package/dist/plugins/frontend-app-plugin.d.ts.map +1 -1
  37. package/dist/plugins/frontend-app-plugin.js +5 -2
  38. package/dist/plugins/frontend-app-plugin.js.map +1 -1
  39. package/dist/plugins/users/__tests__/postgres-store.test.js +1 -0
  40. package/dist/plugins/users/__tests__/postgres-store.test.js.map +1 -1
  41. package/dist/plugins/users/__tests__/users-plugin.test.js +3 -0
  42. package/dist/plugins/users/__tests__/users-plugin.test.js.map +1 -1
  43. package/dist/plugins/users/stores/postgres-store.d.ts.map +1 -1
  44. package/dist/plugins/users/stores/postgres-store.js +59 -1
  45. package/dist/plugins/users/stores/postgres-store.js.map +1 -1
  46. package/dist/plugins/users/types.d.ts +22 -0
  47. package/dist/plugins/users/types.d.ts.map +1 -1
  48. package/dist-ui/assets/index-5nX8fM1a.js +469 -0
  49. package/dist-ui/assets/index-5nX8fM1a.js.map +1 -0
  50. package/dist-ui/index.html +1 -1
  51. package/dist-ui-lib/api/controlPanelApi.d.ts +62 -0
  52. package/dist-ui-lib/components/index.d.ts +2 -1
  53. package/dist-ui-lib/index.js +2588 -2238
  54. package/dist-ui-lib/index.js.map +1 -1
  55. package/dist-ui-lib/pages/APIKeysPage.d.ts +13 -0
  56. package/dist-ui-lib/pages/AcceptInvitationPage.d.ts +28 -0
  57. package/package.json +3 -2
  58. package/src/core/control-panel.ts +8 -8
  59. package/src/plugins/api-keys/api-keys-plugin.ts +397 -0
  60. package/src/plugins/api-keys/index.ts +49 -0
  61. package/src/plugins/api-keys/middleware/bearer-token-auth.ts +250 -0
  62. package/src/plugins/api-keys/middleware/index.ts +12 -0
  63. package/src/plugins/api-keys/stores/index.ts +7 -0
  64. package/src/plugins/api-keys/stores/postgres-store.ts +487 -0
  65. package/src/plugins/api-keys/types.ts +243 -0
  66. package/src/plugins/auth/auth-plugin.ts +1 -1
  67. package/src/plugins/auth/env-config.ts +2 -2
  68. package/src/plugins/frontend-app-plugin.ts +7 -2
  69. package/src/plugins/users/__tests__/postgres-store.test.ts +1 -0
  70. package/src/plugins/users/__tests__/users-plugin.test.ts +3 -0
  71. package/src/plugins/users/stores/postgres-store.ts +69 -0
  72. package/src/plugins/users/types.ts +25 -0
  73. package/ui/src/App.tsx +6 -1
  74. package/ui/src/api/controlPanelApi.ts +157 -0
  75. package/ui/src/components/index.ts +6 -0
  76. package/ui/src/pages/APIKeysPage.tsx +661 -0
  77. package/ui/src/pages/AcceptInvitationPage.tsx +169 -0
  78. package/ui/src/pages/UsersPage.tsx +225 -2
  79. package/dist-ui/assets/index-BfC7mG5L.js +0 -469
  80. package/dist-ui/assets/index-BfC7mG5L.js.map +0 -1
@@ -0,0 +1,360 @@
1
+ /**
2
+ * PostgreSQL API Keys Store
3
+ *
4
+ * API key storage implementation using PostgreSQL with Row-Level Security (RLS).
5
+ * Uses SHA-256 for token hashing (high-entropy keys don't need bcrypt's slowness).
6
+ *
7
+ * RLS Context Pattern:
8
+ * Each operation uses an explicit transaction and sets `app.current_user_id`
9
+ * as a transaction-local configuration variable. The RLS policy checks this
10
+ * variable to enforce that users can only access their own API keys.
11
+ *
12
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
13
+ */
14
+ import crypto from 'crypto';
15
+ import { getLogger } from '@qwickapps/logging';
16
+ // ============================================================================
17
+ // Logging
18
+ // ============================================================================
19
+ const logger = getLogger('api-keys');
20
+ // ============================================================================
21
+ // Token Generation and Hashing
22
+ // ============================================================================
23
+ /**
24
+ * Generate a cryptographically secure API key
25
+ *
26
+ * Token format: `qk_<env>_<32 bytes base64url>`
27
+ * - qk = QwickApps
28
+ * - env = live or test
29
+ * - 32 random bytes = high entropy secret
30
+ *
31
+ * @param isTest Whether this is a test key (default: false)
32
+ * @returns Object with plaintext key, hash, and prefix
33
+ */
34
+ function generateApiKey(isTest = false) {
35
+ const env = isTest ? 'test' : 'live';
36
+ const randomBytes = crypto.randomBytes(32);
37
+ const secret = randomBytes.toString('base64url');
38
+ const key = `qk_${env}_${secret}`;
39
+ // Hash the key for storage (SHA-256 is appropriate for high-entropy tokens)
40
+ const hash = crypto.createHash('sha256').update(key).digest('hex');
41
+ // Prefix for identification (first 12 characters)
42
+ const prefix = key.substring(0, 12);
43
+ return { key, hash, prefix };
44
+ }
45
+ /**
46
+ * Hash an API key using SHA-256
47
+ *
48
+ * We use SHA-256 instead of bcrypt because:
49
+ * 1. API keys are high-entropy (32 random bytes)
50
+ * 2. No need for slow hashing (not user passwords)
51
+ * 3. Faster verification for high-throughput API calls
52
+ *
53
+ * @param key Plaintext API key
54
+ * @returns Hex-encoded SHA-256 hash
55
+ */
56
+ function hashApiKey(key) {
57
+ return crypto.createHash('sha256').update(key).digest('hex');
58
+ }
59
+ /**
60
+ * Verify an API key against its stored hash
61
+ *
62
+ * Uses constant-time comparison to prevent timing attacks.
63
+ *
64
+ * @param key Plaintext API key
65
+ * @param storedHash Hash from database
66
+ * @returns True if key matches hash
67
+ */
68
+ function verifyApiKey(key, storedHash) {
69
+ const keyHash = hashApiKey(key);
70
+ // Constant-time comparison
71
+ return crypto.timingSafeEqual(Buffer.from(keyHash, 'hex'), Buffer.from(storedHash, 'hex'));
72
+ }
73
+ /**
74
+ * Extract prefix from API key
75
+ *
76
+ * @param key Plaintext API key
77
+ * @returns Key prefix (first 12 characters)
78
+ */
79
+ function getKeyPrefix(key) {
80
+ return key.substring(0, 12);
81
+ }
82
+ /**
83
+ * Validate API key format
84
+ *
85
+ * @param key Key to validate
86
+ * @returns True if format is valid
87
+ */
88
+ function isValidKeyFormat(key) {
89
+ // Must start with qk_live_ or qk_test_
90
+ if (!key.startsWith('qk_live_') && !key.startsWith('qk_test_')) {
91
+ return false;
92
+ }
93
+ // Extract secret part
94
+ const parts = key.split('_');
95
+ if (parts.length !== 3) {
96
+ return false;
97
+ }
98
+ const secret = parts[2];
99
+ // Validate length (32 bytes base64url = 43 characters)
100
+ if (secret.length !== 43) {
101
+ return false;
102
+ }
103
+ // Validate characters (base64url: A-Za-z0-9_-)
104
+ const base64urlPattern = /^[A-Za-z0-9_-]+$/;
105
+ return base64urlPattern.test(secret);
106
+ }
107
+ // ============================================================================
108
+ // RLS Helper
109
+ // ============================================================================
110
+ /**
111
+ * Execute a function within an RLS-protected transaction
112
+ *
113
+ * This helper ensures that:
114
+ * 1. All queries run within the same transaction
115
+ * 2. The RLS context is set before any data access
116
+ * 3. The transaction is properly committed or rolled back
117
+ *
118
+ * @param pool PostgreSQL pool
119
+ * @param userId User ID to set as the RLS context
120
+ * @param callback Function to execute within the transaction
121
+ */
122
+ async function withRLSContext(pool, userId, callback) {
123
+ const client = await pool.connect();
124
+ try {
125
+ await client.query('BEGIN');
126
+ // Set transaction-local user context for RLS
127
+ await client.query("SELECT set_config('app.current_user_id', $1, true)", [userId]);
128
+ const result = await callback(client);
129
+ await client.query('COMMIT');
130
+ return result;
131
+ }
132
+ catch (error) {
133
+ await client.query('ROLLBACK');
134
+ throw error;
135
+ }
136
+ finally {
137
+ client.release();
138
+ }
139
+ }
140
+ // ============================================================================
141
+ // PostgreSQL Store Implementation
142
+ // ============================================================================
143
+ /**
144
+ * Create a PostgreSQL API keys store with RLS
145
+ *
146
+ * @param config Configuration including a pg Pool instance
147
+ * @returns ApiKeyStore implementation
148
+ *
149
+ * @example
150
+ * ```ts
151
+ * import { Pool } from 'pg';
152
+ * import { postgresApiKeyStore } from '@qwickapps/server';
153
+ *
154
+ * const pool = new Pool({ connectionString: process.env.DATABASE_URL });
155
+ * const store = postgresApiKeyStore({ pool });
156
+ *
157
+ * // Or with lazy initialization:
158
+ * const store = postgresApiKeyStore({ pool: () => getPostgres().getPool() });
159
+ * ```
160
+ */
161
+ export function postgresApiKeyStore(config) {
162
+ const { pool: poolOrFn, tableName = 'api_keys', schema = 'public', autoCreateTables = true, enableRLS = true, defaultExpirationDays = 90, environment = process.env.NODE_ENV === 'production' ? 'live' : 'test', } = config;
163
+ // Validate environment configuration
164
+ if (environment !== 'test' && environment !== 'live') {
165
+ throw new Error(`Invalid environment: "${environment}". Must be "test" or "live". ` +
166
+ `Check your PostgresApiKeyStoreConfig.environment setting.`);
167
+ }
168
+ // Helper to get pool (supports lazy initialization via function)
169
+ const getPool = () => {
170
+ const pool = typeof poolOrFn === 'function' ? poolOrFn() : poolOrFn;
171
+ if (!pool || typeof pool.query !== 'function') {
172
+ throw new Error('Invalid pool: must have query method');
173
+ }
174
+ return pool;
175
+ };
176
+ const tableFullName = `"${schema}"."${tableName}"`;
177
+ return {
178
+ name: 'postgres',
179
+ async initialize() {
180
+ if (!autoCreateTables)
181
+ return;
182
+ const pool = getPool();
183
+ // Create table with foreign key to users
184
+ await pool.query(`
185
+ CREATE TABLE IF NOT EXISTS ${tableFullName} (
186
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
187
+ user_id UUID NOT NULL REFERENCES "public"."users"(id) ON DELETE CASCADE,
188
+ name VARCHAR(255) NOT NULL,
189
+ key_hash VARCHAR(64) NOT NULL,
190
+ key_prefix VARCHAR(12) NOT NULL,
191
+ key_type VARCHAR(10) NOT NULL CHECK (key_type IN ('m2m', 'pat')),
192
+ scopes TEXT[] NOT NULL DEFAULT '{}',
193
+ last_used_at TIMESTAMPTZ,
194
+ expires_at TIMESTAMPTZ,
195
+ is_active BOOLEAN NOT NULL DEFAULT true,
196
+ created_at TIMESTAMPTZ DEFAULT NOW(),
197
+ updated_at TIMESTAMPTZ DEFAULT NOW()
198
+ );
199
+
200
+ CREATE INDEX IF NOT EXISTS idx_${tableName}_user_id ON ${tableFullName}(user_id);
201
+ CREATE INDEX IF NOT EXISTS idx_${tableName}_key_prefix ON ${tableFullName}(key_prefix);
202
+ CREATE INDEX IF NOT EXISTS idx_${tableName}_key_hash ON ${tableFullName}(key_hash);
203
+ `);
204
+ // Enable RLS if configured
205
+ if (enableRLS) {
206
+ await pool.query(`
207
+ ALTER TABLE ${tableFullName} ENABLE ROW LEVEL SECURITY;
208
+ ALTER TABLE ${tableFullName} FORCE ROW LEVEL SECURITY;
209
+ `);
210
+ // Create or replace the RLS policy
211
+ await pool.query(`
212
+ DROP POLICY IF EXISTS "${tableName}_owner" ON ${tableFullName};
213
+ `);
214
+ // RLS policy: users can only access their own keys
215
+ await pool.query(`
216
+ CREATE POLICY "${tableName}_owner" ON ${tableFullName}
217
+ FOR ALL
218
+ USING (user_id::text = current_setting('app.current_user_id', true))
219
+ WITH CHECK (user_id::text = current_setting('app.current_user_id', true));
220
+ `);
221
+ }
222
+ },
223
+ async create(params) {
224
+ const { user_id, name, key_type, scopes, expires_at } = params;
225
+ // Generate API key based on configured environment
226
+ const isTest = environment === 'test';
227
+ const { key: plaintextKey, hash, prefix } = generateApiKey(isTest);
228
+ // Calculate expiration if not provided
229
+ const expiration = expires_at || (defaultExpirationDays !== null
230
+ ? new Date(Date.now() + defaultExpirationDays * 24 * 60 * 60 * 1000)
231
+ : null);
232
+ return withRLSContext(getPool(), user_id, async (client) => {
233
+ const result = await client.query(`INSERT INTO ${tableFullName}
234
+ (user_id, name, key_hash, key_prefix, key_type, scopes, expires_at)
235
+ VALUES ($1, $2, $3, $4, $5, $6, $7)
236
+ RETURNING *`, [user_id, name, hash, prefix, key_type, scopes, expiration]);
237
+ const row = result.rows[0];
238
+ logger.info('API key created', {
239
+ action: 'api_key.created',
240
+ user_id,
241
+ key_id: row.id,
242
+ key_prefix: row.key_prefix,
243
+ key_type: row.key_type,
244
+ scopes: row.scopes,
245
+ timestamp: new Date().toISOString(),
246
+ });
247
+ return {
248
+ ...row,
249
+ plaintext_key: plaintextKey,
250
+ };
251
+ });
252
+ },
253
+ async list(userId) {
254
+ return withRLSContext(getPool(), userId, async (client) => {
255
+ const result = await client.query(`SELECT * FROM ${tableFullName} WHERE user_id = $1 ORDER BY created_at DESC`, [userId]);
256
+ return result.rows;
257
+ });
258
+ },
259
+ async get(userId, keyId) {
260
+ return withRLSContext(getPool(), userId, async (client) => {
261
+ const result = await client.query(`SELECT * FROM ${tableFullName} WHERE user_id = $1 AND id = $2`, [userId, keyId]);
262
+ if (result.rows.length === 0) {
263
+ return null;
264
+ }
265
+ return result.rows[0];
266
+ });
267
+ },
268
+ async verify(plaintextKey) {
269
+ // Validate format first
270
+ if (!isValidKeyFormat(plaintextKey)) {
271
+ return null;
272
+ }
273
+ const pool = getPool();
274
+ const prefix = getKeyPrefix(plaintextKey);
275
+ // Find key by prefix (no RLS needed for verification)
276
+ const result = await pool.query(`SELECT * FROM ${tableFullName}
277
+ WHERE key_prefix = $1 AND is_active = true`, [prefix]);
278
+ if (result.rows.length === 0) {
279
+ return null;
280
+ }
281
+ const key = result.rows[0];
282
+ // Verify hash
283
+ if (!verifyApiKey(plaintextKey, key.key_hash)) {
284
+ return null;
285
+ }
286
+ // Check expiration
287
+ if (key.expires_at && new Date() > new Date(key.expires_at)) {
288
+ return null;
289
+ }
290
+ return key;
291
+ },
292
+ async update(userId, keyId, params) {
293
+ const updates = [];
294
+ const values = [userId, keyId];
295
+ let paramIndex = 3;
296
+ if (params.name !== undefined) {
297
+ updates.push(`name = $${paramIndex++}`);
298
+ values.push(params.name);
299
+ }
300
+ if (params.scopes !== undefined) {
301
+ updates.push(`scopes = $${paramIndex++}`);
302
+ values.push(params.scopes);
303
+ }
304
+ if (params.expires_at !== undefined) {
305
+ updates.push(`expires_at = $${paramIndex++}`);
306
+ values.push(params.expires_at);
307
+ }
308
+ if (params.is_active !== undefined) {
309
+ updates.push(`is_active = $${paramIndex++}`);
310
+ values.push(params.is_active);
311
+ }
312
+ if (updates.length === 0) {
313
+ // No updates, just return current key
314
+ return this.get(userId, keyId);
315
+ }
316
+ updates.push(`updated_at = NOW()`);
317
+ return withRLSContext(getPool(), userId, async (client) => {
318
+ const result = await client.query(`UPDATE ${tableFullName}
319
+ SET ${updates.join(', ')}
320
+ WHERE user_id = $1 AND id = $2
321
+ RETURNING *`, values);
322
+ if (result.rows.length === 0) {
323
+ return null;
324
+ }
325
+ const updatedKey = result.rows[0];
326
+ logger.info('API key updated', {
327
+ action: 'api_key.updated',
328
+ user_id: userId,
329
+ key_id: keyId,
330
+ changes: Object.keys(params),
331
+ timestamp: new Date().toISOString(),
332
+ });
333
+ return updatedKey;
334
+ });
335
+ },
336
+ async delete(userId, keyId) {
337
+ return withRLSContext(getPool(), userId, async (client) => {
338
+ const result = await client.query(`DELETE FROM ${tableFullName} WHERE user_id = $1 AND id = $2`, [userId, keyId]);
339
+ const deleted = (result.rowCount ?? 0) > 0;
340
+ if (deleted) {
341
+ logger.info('API key deleted', {
342
+ action: 'api_key.deleted',
343
+ user_id: userId,
344
+ key_id: keyId,
345
+ timestamp: new Date().toISOString(),
346
+ });
347
+ }
348
+ return deleted;
349
+ });
350
+ },
351
+ async recordUsage(keyId) {
352
+ const pool = getPool();
353
+ await pool.query(`UPDATE ${tableFullName} SET last_used_at = NOW() WHERE id = $1`, [keyId]);
354
+ },
355
+ async shutdown() {
356
+ // Pool is managed externally, nothing to do here
357
+ },
358
+ };
359
+ }
360
+ //# sourceMappingURL=postgres-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postgres-store.js","sourceRoot":"","sources":["../../../../src/plugins/api-keys/stores/postgres-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,268 @@
1
+ /**
2
+ * API Keys Plugin Types
3
+ *
4
+ * Type definitions for API key authentication and management.
5
+ * Supports PostgreSQL with Row-Level Security (RLS) for data isolation.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+ import { z } from 'zod';
10
+ /**
11
+ * API key scope type
12
+ */
13
+ export type ApiKeyScope = 'read' | 'write' | 'admin';
14
+ /**
15
+ * API key type (M2M = machine-to-machine, PAT = personal access token)
16
+ */
17
+ export type ApiKeyType = 'm2m' | 'pat';
18
+ /**
19
+ * API key record in the database
20
+ */
21
+ export interface ApiKey {
22
+ /** Primary key - UUID */
23
+ id: string;
24
+ /** User ID (foreign key to users table) */
25
+ user_id: string;
26
+ /** Human-readable name for the key */
27
+ name: string;
28
+ /** Hashed API key (SHA-256) */
29
+ key_hash: string;
30
+ /** Key prefix for identification (e.g., 'qk_live_') - stored in plaintext */
31
+ key_prefix: string;
32
+ /** Key type: m2m (machine-to-machine) or pat (personal access token) */
33
+ key_type: ApiKeyType;
34
+ /** Scopes granted to this key */
35
+ scopes: ApiKeyScope[];
36
+ /** Last time this key was used */
37
+ last_used_at: Date | null;
38
+ /** Expiration date (null = never expires) */
39
+ expires_at: Date | null;
40
+ /** Whether the key is active */
41
+ is_active: boolean;
42
+ /** When the key was created */
43
+ created_at: Date;
44
+ /** When the key was last updated */
45
+ updated_at: Date;
46
+ }
47
+ /**
48
+ * API key creation parameters
49
+ */
50
+ export interface CreateApiKeyParams {
51
+ /** User ID who owns this key */
52
+ user_id: string;
53
+ /** Human-readable name for the key */
54
+ name: string;
55
+ /** Key type: m2m or pat */
56
+ key_type: ApiKeyType;
57
+ /** Scopes to grant */
58
+ scopes: ApiKeyScope[];
59
+ /** Optional expiration date */
60
+ expires_at?: Date;
61
+ }
62
+ /**
63
+ * API key update parameters
64
+ */
65
+ export interface UpdateApiKeyParams {
66
+ /** New name (optional) */
67
+ name?: string;
68
+ /** New scopes (optional) */
69
+ scopes?: ApiKeyScope[];
70
+ /** New expiration date (optional) */
71
+ expires_at?: Date;
72
+ /** Activate/deactivate key (optional) */
73
+ is_active?: boolean;
74
+ }
75
+ /**
76
+ * API key with plaintext key (only returned on creation)
77
+ */
78
+ export interface ApiKeyWithPlaintext extends ApiKey {
79
+ /** Plaintext API key - only available on creation */
80
+ plaintext_key: string;
81
+ }
82
+ /**
83
+ * API key store interface - all storage backends must implement this
84
+ */
85
+ export interface ApiKeyStore {
86
+ /** Store name (e.g., 'postgres', 'memory') */
87
+ name: string;
88
+ /**
89
+ * Initialize the store (create tables, RLS policies, etc.)
90
+ */
91
+ initialize(): Promise<void>;
92
+ /**
93
+ * Create a new API key
94
+ * Returns the key with plaintext value (only time plaintext is accessible)
95
+ */
96
+ create(params: CreateApiKeyParams): Promise<ApiKeyWithPlaintext>;
97
+ /**
98
+ * Get all API keys for a user
99
+ */
100
+ list(userId: string): Promise<ApiKey[]>;
101
+ /**
102
+ * Get a specific API key by ID
103
+ * Returns null if key doesn't exist or doesn't belong to user
104
+ */
105
+ get(userId: string, keyId: string): Promise<ApiKey | null>;
106
+ /**
107
+ * Verify an API key and return the associated key record
108
+ * Returns null if key is invalid, expired, or inactive
109
+ */
110
+ verify(plaintextKey: string): Promise<ApiKey | null>;
111
+ /**
112
+ * Update an API key
113
+ * Returns the updated key or null if key doesn't exist
114
+ */
115
+ update(userId: string, keyId: string, params: UpdateApiKeyParams): Promise<ApiKey | null>;
116
+ /**
117
+ * Delete an API key
118
+ * Returns true if key was deleted, false if it didn't exist
119
+ */
120
+ delete(userId: string, keyId: string): Promise<boolean>;
121
+ /**
122
+ * Record key usage (updates last_used_at timestamp)
123
+ */
124
+ recordUsage(keyId: string): Promise<void>;
125
+ /**
126
+ * Shutdown the store
127
+ */
128
+ shutdown(): Promise<void>;
129
+ }
130
+ /**
131
+ * PostgreSQL API key store configuration
132
+ */
133
+ export interface PostgresApiKeyStoreConfig {
134
+ /** PostgreSQL pool instance or a function that returns one (for lazy initialization) */
135
+ pool: unknown | (() => unknown);
136
+ /** Table name (default: 'api_keys') */
137
+ tableName?: string;
138
+ /** Schema name (default: 'public') */
139
+ schema?: string;
140
+ /** Auto-create tables on init (default: true) */
141
+ autoCreateTables?: boolean;
142
+ /** Enable RLS (default: true) */
143
+ enableRLS?: boolean;
144
+ /** Key expiration in days (default: 90, null = never expires) */
145
+ defaultExpirationDays?: number | null;
146
+ /** Environment for key prefix (default: from NODE_ENV, 'test' in non-production, 'live' in production) */
147
+ environment?: 'test' | 'live';
148
+ }
149
+ /**
150
+ * API keys API configuration
151
+ */
152
+ export interface ApiKeysApiConfig {
153
+ /** API route prefix (default: '/api-keys') */
154
+ prefix?: string;
155
+ /** Enable API endpoints (default: true) */
156
+ enabled?: boolean;
157
+ }
158
+ /**
159
+ * API keys plugin configuration
160
+ */
161
+ export interface ApiKeysPluginConfig {
162
+ /** API key storage backend */
163
+ store: ApiKeyStore;
164
+ /** API configuration */
165
+ api?: ApiKeysApiConfig;
166
+ /** Enable debug logging */
167
+ debug?: boolean;
168
+ }
169
+ /**
170
+ * Zod schema for API key scope
171
+ */
172
+ export declare const ApiKeyScopeSchema: z.ZodEnum<["read", "write", "admin"]>;
173
+ /**
174
+ * Zod schema for API key type
175
+ */
176
+ export declare const ApiKeyTypeSchema: z.ZodEnum<["m2m", "pat"]>;
177
+ /**
178
+ * Zod schema for creating an API key
179
+ */
180
+ export declare const CreateApiKeySchema: z.ZodObject<{
181
+ name: z.ZodString;
182
+ key_type: z.ZodEnum<["m2m", "pat"]>;
183
+ scopes: z.ZodArray<z.ZodEnum<["read", "write", "admin"]>, "many">;
184
+ expires_at: z.ZodOptional<z.ZodDate>;
185
+ }, "strip", z.ZodTypeAny, {
186
+ name: string;
187
+ scopes: ("admin" | "read" | "write")[];
188
+ key_type: "m2m" | "pat";
189
+ expires_at?: Date | undefined;
190
+ }, {
191
+ name: string;
192
+ scopes: ("admin" | "read" | "write")[];
193
+ key_type: "m2m" | "pat";
194
+ expires_at?: Date | undefined;
195
+ }>;
196
+ /**
197
+ * Zod schema for updating an API key
198
+ */
199
+ export declare const UpdateApiKeySchema: z.ZodEffects<z.ZodObject<{
200
+ name: z.ZodOptional<z.ZodString>;
201
+ scopes: z.ZodOptional<z.ZodArray<z.ZodEnum<["read", "write", "admin"]>, "many">>;
202
+ expires_at: z.ZodOptional<z.ZodDate>;
203
+ is_active: z.ZodOptional<z.ZodBoolean>;
204
+ }, "strip", z.ZodTypeAny, {
205
+ name?: string | undefined;
206
+ scopes?: ("admin" | "read" | "write")[] | undefined;
207
+ expires_at?: Date | undefined;
208
+ is_active?: boolean | undefined;
209
+ }, {
210
+ name?: string | undefined;
211
+ scopes?: ("admin" | "read" | "write")[] | undefined;
212
+ expires_at?: Date | undefined;
213
+ is_active?: boolean | undefined;
214
+ }>, {
215
+ name?: string | undefined;
216
+ scopes?: ("admin" | "read" | "write")[] | undefined;
217
+ expires_at?: Date | undefined;
218
+ is_active?: boolean | undefined;
219
+ }, {
220
+ name?: string | undefined;
221
+ scopes?: ("admin" | "read" | "write")[] | undefined;
222
+ expires_at?: Date | undefined;
223
+ is_active?: boolean | undefined;
224
+ }>;
225
+ /**
226
+ * Zod schema for API key record
227
+ */
228
+ export declare const ApiKeySchema: z.ZodObject<{
229
+ id: z.ZodString;
230
+ user_id: z.ZodString;
231
+ name: z.ZodString;
232
+ key_hash: z.ZodString;
233
+ key_prefix: z.ZodString;
234
+ key_type: z.ZodEnum<["m2m", "pat"]>;
235
+ scopes: z.ZodArray<z.ZodEnum<["read", "write", "admin"]>, "many">;
236
+ last_used_at: z.ZodNullable<z.ZodDate>;
237
+ expires_at: z.ZodNullable<z.ZodDate>;
238
+ is_active: z.ZodBoolean;
239
+ created_at: z.ZodDate;
240
+ updated_at: z.ZodDate;
241
+ }, "strip", z.ZodTypeAny, {
242
+ name: string;
243
+ id: string;
244
+ scopes: ("admin" | "read" | "write")[];
245
+ created_at: Date;
246
+ expires_at: Date | null;
247
+ user_id: string;
248
+ updated_at: Date;
249
+ is_active: boolean;
250
+ key_type: "m2m" | "pat";
251
+ key_hash: string;
252
+ key_prefix: string;
253
+ last_used_at: Date | null;
254
+ }, {
255
+ name: string;
256
+ id: string;
257
+ scopes: ("admin" | "read" | "write")[];
258
+ created_at: Date;
259
+ expires_at: Date | null;
260
+ user_id: string;
261
+ updated_at: Date;
262
+ is_active: boolean;
263
+ key_type: "m2m" | "pat";
264
+ key_hash: string;
265
+ key_prefix: string;
266
+ last_used_at: Date | null;
267
+ }>;
268
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/plugins/api-keys/types.ts"],"names":[],"mappings":"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"}