feat: add member portal and auth hardening
This commit is contained in:
@@ -11,6 +11,8 @@ export interface ProxmoxConfig {
|
||||
username: string;
|
||||
password: string;
|
||||
realm?: string;
|
||||
tokenName?: string;
|
||||
tokenValue?: string;
|
||||
}
|
||||
|
||||
export interface ContainerSpec {
|
||||
@@ -57,6 +59,17 @@ export class ProxmoxVEIntegration {
|
||||
* Authenticate with Proxmox VE
|
||||
*/
|
||||
async authenticate(): Promise<void> {
|
||||
if (this.config.tokenName && this.config.tokenValue) {
|
||||
this.token = `PVEAPIToken=${this.config.username}!${this.config.tokenName}=${this.config.tokenValue}`;
|
||||
this.tokenExpiry = new Date(Date.now() + 24 * 60 * 60 * 1000);
|
||||
logger.info('Proxmox VE token authentication configured', {
|
||||
host: this.config.host,
|
||||
username: this.config.username,
|
||||
tokenName: this.config.tokenName,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
await proxmoxCircuitBreaker.execute(async () => {
|
||||
return await retryWithBackoff(
|
||||
async () => {
|
||||
@@ -240,7 +253,9 @@ export class ProxmoxVEIntegration {
|
||||
const options: RequestInit = {
|
||||
method,
|
||||
headers: {
|
||||
'Cookie': `PVEAuthCookie=${this.token}`,
|
||||
...(this.config.tokenName && this.config.tokenValue
|
||||
? { Authorization: this.token || '' }
|
||||
: { 'Cookie': `PVEAuthCookie=${this.token}` }),
|
||||
},
|
||||
};
|
||||
|
||||
@@ -281,19 +296,22 @@ export class ProxmoxVEIntegration {
|
||||
// Validate required Proxmox environment variables
|
||||
function getProxmoxConfig(): ProxmoxConfig {
|
||||
const host = process.env.PROXMOX_HOST;
|
||||
const username = process.env.PROXMOX_USERNAME;
|
||||
const username = process.env.PROXMOX_USERNAME || process.env.PROXMOX_USER;
|
||||
const password = process.env.PROXMOX_PASSWORD;
|
||||
const tokenName = process.env.PROXMOX_TOKEN_NAME;
|
||||
const tokenValue = process.env.PROXMOX_TOKEN_VALUE;
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
if (!host) {
|
||||
throw new Error('PROXMOX_HOST environment variable is required in production');
|
||||
}
|
||||
if (!username) {
|
||||
throw new Error('PROXMOX_USERNAME environment variable is required in production');
|
||||
}
|
||||
if (!password) {
|
||||
throw new Error('PROXMOX_PASSWORD environment variable is required in production');
|
||||
}
|
||||
const hasPasswordAuth = Boolean(host && username && password);
|
||||
const hasTokenAuth = Boolean(host && username && tokenName && tokenValue);
|
||||
|
||||
if (process.env.NODE_ENV === 'production' && !hasPasswordAuth && !hasTokenAuth) {
|
||||
logger.warn('Proxmox integration environment is incomplete; IRU deployment features will remain unavailable', {
|
||||
hasHost: Boolean(host),
|
||||
hasUsername: Boolean(username),
|
||||
hasPassword: Boolean(password),
|
||||
hasTokenName: Boolean(tokenName),
|
||||
hasTokenValue: Boolean(tokenValue),
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -302,6 +320,8 @@ function getProxmoxConfig(): ProxmoxConfig {
|
||||
username: username || 'root',
|
||||
password: password || '',
|
||||
realm: process.env.PROXMOX_REALM || 'pam',
|
||||
tokenName,
|
||||
tokenValue,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user