feat: add SESSION_SECRET_FILE and OAUTH_CLIENT_SECRET_FILE env vars
This commit is contained in:
committed by
Linus Rath
parent
9c5daa3918
commit
f9052eb23f
@@ -1,3 +1,4 @@
|
||||
import { unlink, writeFileSync } from "fs";
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||
|
||||
// Mock NextResponse before importing the route
|
||||
@@ -24,6 +25,7 @@ describe('config API route', () => {
|
||||
delete process.env.OAUTH_CLIENT_ID;
|
||||
delete process.env.OAUTH_ISSUER_URL;
|
||||
delete process.env.SESSION_SECRET;
|
||||
delete process.env.SESSION_SECRET_FILE;
|
||||
delete process.env.SETTINGS_SYNC_ENABLED;
|
||||
delete process.env.STALWART_FEATURES;
|
||||
delete process.env.DEV_MOCK_JMAP;
|
||||
@@ -128,6 +130,19 @@ describe('config API route', () => {
|
||||
|
||||
const config = await getConfig();
|
||||
|
||||
expect(config.rememberMeEnabled).toBe(true);
|
||||
});
|
||||
|
||||
it('should enable rememberMe when SESSION_SECRET_FILE is set', async () => {
|
||||
writeFileSync('./session-secret', 'test-secret');
|
||||
process.env.SESSION_SECRET_FILE = './session-secret';
|
||||
|
||||
const config = await getConfig();
|
||||
|
||||
unlink('./session-secret', (err) => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
expect(config.rememberMeEnabled).toBe(true);
|
||||
});
|
||||
|
||||
@@ -138,6 +153,23 @@ describe('config API route', () => {
|
||||
|
||||
process.env.SESSION_SECRET = 'test-secret';
|
||||
const config2 = await getConfig();
|
||||
expect(config2.settingsSyncEnabled).toBe(true);
|
||||
});
|
||||
|
||||
it('should enable settingsSync only when both SESSION_SECRET_FILE and SETTINGS_SYNC_ENABLED are set', async () => {
|
||||
process.env.SETTINGS_SYNC_ENABLED = 'true';
|
||||
const config1 = await getConfig();
|
||||
expect(config1.settingsSyncEnabled).toBe(false);
|
||||
|
||||
writeFileSync('./session-secret', 'test-secret');
|
||||
process.env.SESSION_SECRET_FILE = './session-secret';
|
||||
|
||||
const config2 = await getConfig();
|
||||
|
||||
unlink('./session-secret', (err) => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
expect(config2.settingsSyncEnabled).toBe(true);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { cookies } from 'next/headers';
|
||||
import { NextResponse } from 'next/server';
|
||||
import { createCipheriv, createDecipheriv, randomBytes, createHash } from 'node:crypto';
|
||||
import { readFileEnv } from '@/lib/read-file-env';
|
||||
import { ADMIN_SESSION_COOKIE, DEFAULT_ADMIN_SESSION_TTL } from './types';
|
||||
import type { AdminSessionPayload } from './types';
|
||||
|
||||
@@ -11,7 +12,7 @@ const TAG_LENGTH = 16;
|
||||
const MIN_SECRET_LENGTH = 32;
|
||||
|
||||
function getKey(): Buffer {
|
||||
const secret = process.env.SESSION_SECRET;
|
||||
const secret = process.env.SESSION_SECRET || readFileEnv(process.env.SESSION_SECRET_FILE);
|
||||
if (!secret) throw new Error('SESSION_SECRET not configured');
|
||||
if (secret.length < MIN_SECRET_LENGTH) {
|
||||
throw new Error(
|
||||
|
||||
+2
-1
@@ -1,5 +1,6 @@
|
||||
import { createCipheriv, createDecipheriv, randomBytes, createHash } from 'node:crypto';
|
||||
import { logger } from '@/lib/logger';
|
||||
import { readFileEnv } from '@/lib/read-file-env';
|
||||
|
||||
const ALGORITHM = 'aes-256-gcm';
|
||||
const IV_LENGTH = 12;
|
||||
@@ -8,7 +9,7 @@ const TAG_LENGTH = 16;
|
||||
const MIN_SECRET_LENGTH = 32;
|
||||
|
||||
function getKey(): Buffer {
|
||||
const secret = process.env.SESSION_SECRET;
|
||||
const secret = process.env.SESSION_SECRET || readFileEnv(process.env.SESSION_SECRET_FILE);
|
||||
if (!secret) throw new Error('SESSION_SECRET not configured');
|
||||
if (secret.length < MIN_SECRET_LENGTH) {
|
||||
throw new Error(
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { logger } from '@/lib/logger';
|
||||
import { discoverOAuth } from '@/lib/oauth/discovery';
|
||||
import type { OAuthMetadata } from '@/lib/oauth/discovery';
|
||||
import { readFileEnv } from '@/lib/read-file-env';
|
||||
|
||||
const CLIENT_SECRET = process.env.OAUTH_CLIENT_SECRET || '';
|
||||
const CLIENT_SECRET = process.env.OAUTH_CLIENT_SECRET || readFileEnv(process.env.OAUTH_CLIENT_SECRET_FILE) || '';
|
||||
|
||||
export function getRequiredConfig() {
|
||||
const clientId = process.env.OAUTH_CLIENT_ID;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { readFileSync } from "fs";
|
||||
|
||||
export function readFileEnv(path: string | undefined): string | null {
|
||||
if (!path) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return readFileSync(path, "utf-8").trim();
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -3,13 +3,14 @@ import { readFile, writeFile, unlink, mkdir, rename } from 'node:fs/promises';
|
||||
import { existsSync } from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import { logger } from '@/lib/logger';
|
||||
import { readFileEnv } from '@/lib/read-file-env';
|
||||
|
||||
const ALGORITHM = 'aes-256-gcm';
|
||||
const IV_LENGTH = 12;
|
||||
const TAG_LENGTH = 16;
|
||||
|
||||
function getKey(): Buffer {
|
||||
const secret = process.env.SESSION_SECRET;
|
||||
const secret = process.env.SESSION_SECRET || readFileEnv(process.env.SESSION_SECRET_FILE);
|
||||
if (!secret) throw new Error('SESSION_SECRET not configured');
|
||||
return createHash('sha256').update(secret).digest();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user