mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-04-27 15:17:38 +00:00
server: Allow empty username to restore b2 behaviour. Fixes #59
This commit is contained in:
parent
38c308e34c
commit
9101613351
3 changed files with 37 additions and 21 deletions
|
|
@ -142,7 +142,8 @@ final class BunServer {
|
||||||
.replacingOccurrences(of: "$", with: "\\$")
|
.replacingOccurrences(of: "$", with: "\\$")
|
||||||
.replacingOccurrences(of: "`", with: "\\`")
|
.replacingOccurrences(of: "`", with: "\\`")
|
||||||
.replacingOccurrences(of: "\\", with: "\\\\")
|
.replacingOccurrences(of: "\\", with: "\\\\")
|
||||||
vibetunnelArgs += " --username admin --password \"\(escapedPassword)\""
|
// Use password-only mode for better UX - users can enter any username
|
||||||
|
vibetunnelArgs += " --password \"\(escapedPassword)\""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,10 +52,23 @@ export function createAuthMiddleware(config: AuthConfig) {
|
||||||
const credentials = Buffer.from(base64Credentials, 'base64').toString('utf8');
|
const credentials = Buffer.from(base64Credentials, 'base64').toString('utf8');
|
||||||
const [username, password] = credentials.split(':');
|
const [username, password] = credentials.split(':');
|
||||||
|
|
||||||
if (username === config.basicAuthUsername && password === config.basicAuthPassword) {
|
// If no username is configured, accept any username as long as password matches
|
||||||
return next();
|
// This allows for password-only authentication mode
|
||||||
|
if (!config.basicAuthUsername) {
|
||||||
|
// Password-only mode: ignore username, only check password
|
||||||
|
if (password === config.basicAuthPassword) {
|
||||||
|
logger.log(chalk.green(`authenticated via password-only mode from ${req.ip}`));
|
||||||
|
return next();
|
||||||
|
} else {
|
||||||
|
logger.warn(`failed password-only auth attempt from ${req.ip}`);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.warn(`failed basic auth attempt from ${req.ip} for user: ${username}`);
|
// Username+password mode: check both
|
||||||
|
if (username === config.basicAuthUsername && password === config.basicAuthPassword) {
|
||||||
|
return next();
|
||||||
|
} else {
|
||||||
|
logger.warn(`failed basic auth attempt from ${req.ip} for user: ${username}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -218,14 +218,9 @@ function parseArgs(): Config {
|
||||||
// Validate configuration
|
// Validate configuration
|
||||||
function validateConfig(config: ReturnType<typeof parseArgs>) {
|
function validateConfig(config: ReturnType<typeof parseArgs>) {
|
||||||
// Validate local auth configuration
|
// Validate local auth configuration
|
||||||
if (
|
if (config.basicAuthUsername && !config.basicAuthPassword) {
|
||||||
(config.basicAuthUsername && !config.basicAuthPassword) ||
|
logger.error('Password must be provided when username is specified');
|
||||||
(!config.basicAuthUsername && config.basicAuthPassword)
|
logger.error('Use --username and --password together');
|
||||||
) {
|
|
||||||
logger.error('Both username and password must be provided for authentication');
|
|
||||||
logger.error(
|
|
||||||
'Use --username and --password, or set both VIBETUNNEL_USERNAME and VIBETUNNEL_PASSWORD'
|
|
||||||
);
|
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -267,10 +262,11 @@ function validateConfig(config: ReturnType<typeof parseArgs>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// If not HQ mode and no HQ URL, warn about authentication
|
// If not HQ mode and no HQ URL, warn about authentication
|
||||||
if (!config.basicAuthUsername && !config.basicAuthPassword && !config.isHQMode && !config.hqUrl) {
|
if (!config.basicAuthPassword && !config.isHQMode && !config.hqUrl) {
|
||||||
logger.warn('No authentication configured');
|
logger.warn('No authentication configured');
|
||||||
|
logger.warn('Set VIBETUNNEL_PASSWORD or use --password flag for password-only authentication');
|
||||||
logger.warn(
|
logger.warn(
|
||||||
'Set VIBETUNNEL_USERNAME and VIBETUNNEL_PASSWORD or use --username and --password flags'
|
'Or use --username and --password flags together for username+password authentication'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -509,7 +505,7 @@ export async function createApp(): Promise<AppInstance> {
|
||||||
createPushRoutes({
|
createPushRoutes({
|
||||||
vapidManager,
|
vapidManager,
|
||||||
pushNotificationService,
|
pushNotificationService,
|
||||||
bellEventHandler,
|
bellEventHandler: bellEventHandler ?? undefined,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
logger.debug('Mounted push notification routes');
|
logger.debug('Mounted push notification routes');
|
||||||
|
|
@ -576,14 +572,20 @@ export async function createApp(): Promise<AppInstance> {
|
||||||
chalk.green(`VibeTunnel Server running on http://${displayAddress}:${actualPort}`)
|
chalk.green(`VibeTunnel Server running on http://${displayAddress}:${actualPort}`)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (config.basicAuthUsername && config.basicAuthPassword) {
|
if (config.basicAuthPassword) {
|
||||||
logger.log(chalk.green('Basic authentication: ENABLED'));
|
if (config.basicAuthUsername) {
|
||||||
logger.log(`Username: ${config.basicAuthUsername}`);
|
logger.log(chalk.green('Authentication: USERNAME + PASSWORD'));
|
||||||
logger.log(`Password: ${'*'.repeat(config.basicAuthPassword.length)}`);
|
logger.log(`Username: ${config.basicAuthUsername}`);
|
||||||
|
logger.log(`Password: ${'*'.repeat(config.basicAuthPassword.length)}`);
|
||||||
|
} else {
|
||||||
|
logger.log(chalk.green('Authentication: PASSWORD ONLY'));
|
||||||
|
logger.log(`Password: ${'*'.repeat(config.basicAuthPassword.length)}`);
|
||||||
|
logger.log(chalk.gray('(Any username will be accepted)'));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
logger.warn('Server running without authentication');
|
logger.warn('Server running without authentication');
|
||||||
logger.warn(
|
logger.warn(
|
||||||
'Anyone can access this server. Use --username and --password or set VIBETUNNEL_USERNAME and VIBETUNNEL_PASSWORD'
|
'Anyone can access this server. Use --password for password-only auth or --username and --password for full auth'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -705,7 +707,7 @@ export async function startVibeTunnelServer() {
|
||||||
if (appInstance.pushNotificationService) {
|
if (appInstance.pushNotificationService) {
|
||||||
_subscriptionCleanupInterval = setInterval(
|
_subscriptionCleanupInterval = setInterval(
|
||||||
() => {
|
() => {
|
||||||
appInstance.pushNotificationService!.cleanupInactiveSubscriptions().catch((error) => {
|
appInstance.pushNotificationService?.cleanupInactiveSubscriptions().catch((error) => {
|
||||||
logger.error('Failed to cleanup inactive subscriptions:', error);
|
logger.error('Failed to cleanup inactive subscriptions:', error);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue