Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 98x 98x 98x 98x 98x 153x 153x 153x 153x 153x 153x 153x 153x 98x 98x | /**
* Session Storage Factory
*
* Creates and configures the appropriate storage backend based on configuration.
*/
import { SessionStorageBackend, StorageConfig } from './types';
import { MemoryStorageBackend } from './memory';
import { FileStorageBackend } from './file';
import { PostgreSQLStorageBackend } from './postgresql';
import { logInfo } from '../../logger';
/**
* Create a storage backend based on configuration
*
* Configuration can come from:
* 1. Explicit StorageConfig object
* 2. Environment variables
*
* Environment variables:
* - OAUTH_STORAGE_TYPE: "memory" | "file" | "postgresql" (default: "memory")
* - OAUTH_STORAGE_FILE_PATH: Path for file storage (default: ./data/oauth-sessions.json)
* - OAUTH_STORAGE_POSTGRESQL_URL: PostgreSQL connection string
* - OAUTH_STORAGE_TABLE_PREFIX: PostgreSQL table prefix (default: "oauth_")
*/
export function createStorageBackend(config?: StorageConfig): SessionStorageBackend {
// Use config if provided, otherwise read from environment
const storageType = config?.type ?? getEnvStorageType();
switch (storageType) {
case 'file':
return createFileBackend(config);
case 'postgresql':
return createPostgreSQLBackend();
case 'memory':
default:
return createMemoryBackend();
}
}
function getEnvStorageType(): 'memory' | 'file' | 'postgresql' {
const type = process.env.OAUTH_STORAGE_TYPE?.toLowerCase();
Iif (type === 'file' || type === 'postgresql') {
return type;
}
return 'memory';
}
function createMemoryBackend(): MemoryStorageBackend {
logInfo('Using in-memory session storage (sessions will be lost on restart)');
return new MemoryStorageBackend();
}
function createFileBackend(config?: StorageConfig): FileStorageBackend {
const filePath =
config?.file?.path ?? process.env.OAUTH_STORAGE_FILE_PATH ?? './data/oauth-sessions.json';
const saveInterval =
config?.file?.saveInterval ?? parseInt(process.env.OAUTH_STORAGE_SAVE_INTERVAL ?? '30000', 10);
logInfo('Using file-based session storage', { filePath, saveInterval });
return new FileStorageBackend({
filePath,
saveInterval,
});
}
function createPostgreSQLBackend(): PostgreSQLStorageBackend {
// Prisma uses OAUTH_STORAGE_POSTGRESQL_URL or DATABASE_URL from environment
const connectionString = process.env.OAUTH_STORAGE_POSTGRESQL_URL ?? process.env.DATABASE_URL;
if (!connectionString) {
throw new Error(
'PostgreSQL storage requires a connection string. ' +
'Set OAUTH_STORAGE_POSTGRESQL_URL or DATABASE_URL environment variable',
);
}
logInfo('Using PostgreSQL session storage (via Prisma)');
return new PostgreSQLStorageBackend();
}
/**
* Get storage type from environment or config
*/
export function getStorageType(config?: StorageConfig): 'memory' | 'file' | 'postgresql' {
return config?.type ?? getEnvStorageType();
}
/**
* Validate storage configuration
*/
export function validateStorageConfig(config?: StorageConfig): string[] {
const errors: string[] = [];
const type = getStorageType(config);
if (type === 'postgresql') {
// Prisma uses OAUTH_STORAGE_POSTGRESQL_URL or DATABASE_URL
const connectionString = process.env.OAUTH_STORAGE_POSTGRESQL_URL ?? process.env.DATABASE_URL;
if (!connectionString) {
errors.push(
'PostgreSQL storage requires OAUTH_STORAGE_POSTGRESQL_URL or DATABASE_URL environment variable',
);
}
}
if (type === 'file') {
const filePath = config?.file?.path ?? process.env.OAUTH_STORAGE_FILE_PATH;
// File path is optional - defaults to ./data/oauth-sessions.json
if (filePath) {
// Basic path validation
if (filePath.includes('..')) {
errors.push("File storage path must not contain '..'");
}
}
}
return errors;
}
|